﻿using System;
using System.Linq;
using System.Threading;
using D3;
using NYTBD.Common;

namespace NYTBD.Modules
{
    internal class Pdp11
    {
        public static ulong ExitGameButtonId = 0x5DB09161C4D6B4C6;
        public static ulong SkipSequenceButtonId = 0x2289FE26DA955A81;
        public static ulong ConfirmSkipSequenceButtonId = 0x891D21408238D18E;
        public static ulong InventoryButtonExitId = 0x368FF8C552241695;
        public static ulong DurabilityIndicatorId = 0x368FF8C552241695;
        public static ulong ChangeQuestButtonId = 0xC4A9CC94C0A929B;
        public static ulong SelectQuestButtonId = 0x1AE2209980AAEA69;
        public static ulong SelectQuestConfirmButtonId = 0xB4433DA3F648A992;
        public static ulong SkipNCPConversationId = 0x942F41B6B5346714;
        public static ulong RepairAllButtonId = 0x80F5D06A035848A5;
        public static ulong ReviveButtonId = 0xBFAAF48BA9316742;
        public static ulong ResumeGame = 0x51A3923949DC80B7;

        public delegate void UICallback(string action);

        public static void ExitGame()
        {
            UIElement ui = UIElement.Get(ExitGameButtonId);

            if (ui != null)
            {
                ui.Click();
            }
        }


        public static void EnterGame()
        {
            /*TaskManager.AddTask(TaskPriority.Base, "Enter Game",
                delegate()
                    {*/
                        UIElement ui = UIElement.Get(ResumeGame);

                        if (ui != null)
                        {
                            ui.Click();
                        }
                        Thread.Sleep(3000);
                        while (Me.Name == null)
                        {
                            Thread.Sleep(3000);
                        }
                   // });

        }

        /// <summary>
        /// clicks the revive button once per second. does not handle the popups yet
        /// </summary>
        public static void Revive()
        {
            // 20DDD3F4: BFAAF48BA9316742 Root.NormalLayer.deathmenu_dialog.dialog_main.button_revive_at_checkpoint (Visible: True)
            UIElement btn = UIElement.Get(ReviveButtonId);
            while (btn != default(UIElement) && btn.Visible)
            {
                btn.Click();
                Thread.Sleep(1000);
            }
        }

        public static UIElement GetUIElement(ulong ann)
        {
            return UIElement.Get().Where(x => x.Hash == (long) ann).FirstOrDefault();
        }

        public static UIElement GetUIElement(String name)
        {
            return UIElement.Get().Where(x => x.Name.Contains(name)).FirstOrDefault();
        }

        /// <summary>
        /// buy window needs to be open. repair tab needs not be selected though
        /// </summary>
        public static void RepairAll()
        {
            // 1EFC12BC: 80F5D06A035848A5 Root.NormalLayer.shop_dialog_mainPage.repair_dialog.RepairAll (Visible: True)
            UIElement btn = UIElement.Get(RepairAllButtonId);
            if (btn != default(UIElement))
            {
                btn.Click();
            }


        }


        public static void CloseInventory()
        {
            UIElement btn = UIElement.Get(InventoryButtonExitId);

            if (btn.Visible)
                btn.Click();
        }

        public static int GetDurabilityInfo()
        {
            // 0 : Invisible, 1: yellow, 2: red
            UIElement indicator = UIElement.Get(DurabilityIndicatorId);
            if (indicator != default(UIElement) && indicator.Visible) return 1;
            return 0;
        }

        public static void SkipConversation()
        {
            UIElement advKey = UIElement.Get(SkipNCPConversationId);
            while (advKey.Visible)
            {
                advKey.Click();
                Thread.Sleep(45);
            }
        }

        public static void ClickUI(string name, bool visible)
        {
            UIElement e = UIElement.Get().FirstOrDefault(x => x.Name.Contains(name));
            if (e != null && e != default (UIElement))
            e.Click();
        }

        public static void ChangeQuest(uint listIndex)
        {
            UIElement changeQuest = UIElement.Get(ChangeQuestButtonId);
            changeQuest.Click();
            Thread.Sleep(469);

            UIElement button = default(UIElement);

            button = UIElement.Get().Where(x => x.Name.EndsWith(string.Format("_item{0}", listIndex))).FirstOrDefault();

            button.Click();
            Thread.Sleep(478);

            UIElement.Get(SelectQuestButtonId).Click(); // select quest
            Thread.Sleep(730);
            UIElement ok = UIElement.Get(SelectQuestConfirmButtonId);
            if (ok != null && ok.Visible)
            {
                ok.Click();
            }

            Thread.Sleep(1000);
        }

        public static void UseWaypoint(uint listpos)
        {
            ClickUI(string.Format("{0}.wrapper.button", listpos), true);
        }

        public static void SkipSequence()
        {
            UIElement skipSequence = UIElement.Get(SkipSequenceButtonId);
            UIElement confirmButton = UIElement.Get(ConfirmSkipSequenceButtonId);

            for (int i = 0; i < 10 && skipSequence.Visible == false; i++)
            {
                Thread.Sleep(500);
            }

            if (skipSequence.Visible == false)
            {
                throw new Exception("Skip Sequence UIElement is not visible!");
            }

            skipSequence.Click();

            for (int i = 0; i < 10 && confirmButton.Visible == false; i++)
            {
                Thread.Sleep(500);
            }

            if (skipSequence.Visible == false)
            {
                throw new Exception("Confirm Button UIElement is not visible!");
            }

            confirmButton.Click();

            for (int i = 0; i < 10 && confirmButton.Visible; i++)
            {
                Thread.Sleep(500);
            }

            if (confirmButton.Visible)
            {
                throw new Exception("Confirm Button UIElement is still visible!");
            }

            // Wait out sequence post effect..
            Thread.Sleep(5500);
        }
    }
}